'use client';

import {
  type ChangeEvent,
  type Dispatch,
  type FormEvent,
  type SetStateAction,
  useEffect,
  useState,
} from 'react';
import { useMutation } from '@tanstack/react-query';
import diff from 'microdiff';
import type {
  IConfigCaptchaItem,
  IConfigImage,
  IDifference,
} from '@/interfaces';
import { updateImageConfig } from '@/services/api';
import useToast from '@/hooks/useToast';
import { getDiffData } from '@/lib/tool';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import classNames from 'classnames';
import { type IConfigImageContentType } from '@/types';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function UpdateConfigImage(
  this: any,
  {
    source,
    translatedFields,
  }: {
    source: IConfigImage;
    translatedFields: PrefixedTTranslatedFields<'configAdminPage'>;
  },
) {
  const [tabIndex, setTabIndex] = useState(0);
  const [conditionsFulfilled, setConditionsFulfilled] = useState(false);
  const { show } = useToast();

  function onClickTab(index: number) {
    if (!conditionsFulfilled && index !== 0) {
      show({
        type: 'WARNING',
        message: translatedFields.config.image.verifyTip,
      });
      return;
    }
    setTabIndex(index);
  }

  return (
    <Box>
      <div className="vstack gap-4">
        <nav className="nav nav-pills flex-column flex-sm-row">
          <a
            onClick={onClickTab.bind(this, 0)}
            className={classNames(
              'flex-sm-fill text-sm-center nav-link cursor-pointer',
              {
                'bg-light': tabIndex === 0,
              },
            )}
          >
            {translatedFields.config.image.verify}
          </a>
          <a
            onClick={onClickTab.bind(this, 1)}
            className={classNames(
              'flex-sm-fill text-sm-center nav-link cursor-pointer',
              {
                'bg-light': tabIndex === 1,
              },
            )}
          >
            {translatedFields.config.image.login}
          </a>
          <a
            onClick={onClickTab.bind(this, 2)}
            className={classNames(
              'flex-sm-fill text-sm-center nav-link cursor-pointer',
              {
                'bg-light': tabIndex === 2,
              },
            )}
          >
            {translatedFields.config.image.register}
          </a>
        </nav>

        {tabIndex === 0 && (
          <Item
            type="VERIFY"
            source={source}
            translatedFields={translatedFields}
            setConditionsFulfilled={setConditionsFulfilled}
          />
        )}

        {tabIndex === 1 && (
          <Item
            type="LOGIN"
            source={source}
            translatedFields={translatedFields}
          />
        )}

        {tabIndex === 2 && (
          <Item
            type="REGISTER"
            source={source}
            translatedFields={translatedFields}
          />
        )}
      </div>
    </Box>
  );
}

const Item = ({
  type,
  source,
  translatedFields,
  setConditionsFulfilled,
}: {
  type: IConfigImageContentType;
  source: IConfigImage;
  translatedFields: PrefixedTTranslatedFields<'configAdminPage'>;
  setConditionsFulfilled?: Dispatch<SetStateAction<boolean>>;
}) => {
  const { show } = useToast();
  const [form, setForm] = useState<IConfigCaptchaItem>({
    enable: false,
    expire: 'PT5M',
    total: 5,
    interval: 'PT1M',
    recoveryTime: 'PT24H',
    length: 4,
    alphanumeric: false,
    alphabetic: false,
    ascii: false,
    numeric: true,
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const updateImageConfigMutation = useMutation(updateImageConfig);

  useEffect(() => {
    const diffData = diff(
      source.list[type]?.captchaConfig ?? {
        enable: false,
        expire: 'PT5M',
        total: 5,
        interval: 'PT1M',
        recoveryTime: 'PT24H',
        length: 4,
        alphanumeric: false,
        alphabetic: false,
        ascii: false,
        numeric: true,
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, source, type]);
  useEffect(() => {
    if (typeof setConditionsFulfilled === 'function') {
      setConditionsFulfilled(form.enable);
    }
  }, [form.enable, setConditionsFulfilled]);

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      const data = getDiffData(differenceData);
      await updateImageConfigMutation.mutateAsync({
        data: {
          list: {
            [type]: data,
          },
        },
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.updateCompleted,
      });
    } catch (e) {
      updateImageConfigMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
    }
  }

  function onChangeForm(e: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
    const name = e.target.name;
    const value = e.target.value;

    if (
      name === 'enable' ||
      name === 'alphanumeric' ||
      name === 'alphabetic' ||
      name === 'ascii' ||
      name === 'numeric'
    ) {
      setForm({
        ...form,
        [name]: value === 'true',
      });
    } else if (name === 'total' || name === 'length') {
      setForm({
        ...form,
        [name]: parseInt(value),
      });
    } else {
      setForm({
        ...form,
        [name]: value,
      });
    }
  }

  return (
    <Box>
      <form onSubmit={onClickSave} className="vstack gap-4">
        <div>
          <label className="form-label">
            {translatedFields.config.image.enable}
          </label>
          <select
            name="enable"
            value={form.enable + ''}
            onChange={onChangeForm}
            className="form-select"
            aria-label="enable"
          >
            <option value="true">true</option>
            <option value="false">false</option>
          </select>
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.expire}
          </label>
          <input
            type="text"
            className="form-control"
            name="expire"
            value={form.expire}
            onChange={onChangeForm}
            aria-describedby="expire"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.total}
          </label>
          <input
            min={1}
            type="number"
            className="form-control"
            name="total"
            value={form.total}
            onChange={onChangeForm}
            aria-describedby="total"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.interval}
          </label>
          <input
            type="text"
            className="form-control"
            name="interval"
            value={form.interval}
            onChange={onChangeForm}
            aria-describedby="interval"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.recoveryTime}
          </label>
          <input
            type="text"
            className="form-control"
            name="recoveryTime"
            value={form.recoveryTime}
            onChange={onChangeForm}
            aria-describedby="recoveryTime"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.length}
          </label>
          <input
            min={1}
            type="number"
            className="form-control"
            name="length"
            value={form.length}
            onChange={onChangeForm}
            aria-describedby="length"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.alphanumeric}
          </label>
          <select
            name="alphanumeric"
            value={form.alphanumeric + ''}
            onChange={onChangeForm}
            className="form-select"
            aria-label="alphanumeric"
          >
            <option value="true">true</option>
            <option value="false">false</option>
          </select>
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.alphabetic}
          </label>
          <select
            name="alphabetic"
            value={form.alphabetic + ''}
            onChange={onChangeForm}
            className="form-select"
            aria-label="alphabetic"
          >
            <option value="true">true</option>
            <option value="false">false</option>
          </select>
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.ascii}
          </label>
          <select
            name="ascii"
            value={form.ascii + ''}
            onChange={onChangeForm}
            className="form-select"
            aria-label="ascii"
          >
            <option value="true">true</option>
            <option value="false">false</option>
          </select>
        </div>

        <div>
          <label className="form-label">
            {translatedFields.config.image.numeric}
          </label>
          <select
            name="numeric"
            value={form.numeric + ''}
            onChange={onChangeForm}
            className="form-select"
            aria-label="numeric"
          >
            <option value="true">true</option>
            <option value="false">false</option>
          </select>
        </div>

        <button
          type="submit"
          disabled={updateImageConfigMutation.isLoading || isDisabledSave}
          className="btn btn-success col col-lg-2 my-4"
        >
          {updateImageConfigMutation.isLoading && <Spinner classs="me-2" />}
          {translatedFields.operate.update}
        </button>
      </form>
    </Box>
  );
};
